#include <display_manager.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>

static int fd_fb;
static struct fb_var_screeninfo var;	/* Current var */
static int screen_size;
static unsigned char *fb_base;
static unsigned int line_width;
static unsigned int pixel_width;

static int frambuffer_GetBuffer(PDispBuffer ptDisplayBuffer)
{
	/******************得到frambuffer信息******************/
	ptDisplayBuffer->iXres = var.xres;
	ptDisplayBuffer->iYres = var.yres;
	ptDisplayBuffer->iBpp   = var.bits_per_pixel;
	ptDisplayBuffer->buff	= (char * )fb_base;
	return 0;
}

static int frambuffer_FlushRegion( PRegion ptRegion ,PDispBuffer ptDispBuffer)
{
	return 0;
}

static int frambuffer_DeviceInit(void)
{
	/******************打开LCD设备文件******************/
	fd_fb = open("/dev/fb0", O_RDWR);
	if (fd_fb < 0)
	{
		printf("can't open /dev/fb0\n");
		return -1;
	}
	/******************获取LCD设备信息******************/
	
	if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
	{
		printf("can't get var\n");
		return -1;
	}	
	line_width  = var.xres * var.bits_per_pixel / 8;
	pixel_width = var.bits_per_pixel / 8;
	screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
	fb_base = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);

	if (fb_base == (unsigned char *)-1)
	{
		printf("can't mmap\n");
		return -1;
	}
	/******************成功返回0******************/

	return 0;
}
static int frambuffer_DeviceExit(void)
{
	munmap(fb_base, screen_size);
	close(fd_fb);
	return 0;
}

static DispOpr g_tFrambuffer = {
	.name = "frambuffer",
	.GetBuffer = frambuffer_GetBuffer,
	.FlushRegion = frambuffer_FlushRegion,
	.DeviceInit = frambuffer_DeviceInit,
	.DeviceExit = frambuffer_DeviceExit,
};

void frambufferInit(void)
{
	RegisterDisplay(&g_tFrambuffer);
}

